package jbrowser;

import com.sun.security.auth.login.ConfigFile;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import jbrowser.utils.Properties;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.Policy;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.security.auth.login.Configuration;
import javax.swing.SwingUtilities;
import jbrowser.gui.Window;
import jbrowser.security.DefaultSecurityManagerService;
import org.apache.commons.io.FileUtils;
import sun.security.provider.PolicyFile;

public class JBrowser {

    private static Logger logger;
    private static File homeFolder;
    private static Properties properties;

    public static File getHome() {
        return homeFolder;
    }

    public static Window newWindow() {
        Window window = new Window();
        String strWidth = JBrowser.getProperties().getProperty("window.size.width");
        String strHeight = JBrowser.getProperties().getProperty("window.size.height");
        if (strWidth != null && strHeight != null) {
            window.setPreferredSize(new Dimension(Integer.parseInt(strWidth), Integer.parseInt(strHeight)));
            window.setSize(new Dimension(Integer.parseInt(strWidth), Integer.parseInt(strHeight)));
        }
        int state = Integer.parseInt(JBrowser.getProperties().getProperty("window.size.state"));
        switch (state) {
            case Frame.NORMAL:
            case Frame.ICONIFIED:
                window.setExtendedState(Frame.NORMAL);
                GraphicsConfiguration gc = window.getGraphicsConfiguration();
                Rectangle bounds = gc.getBounds();
                Dimension size = window.getPreferredSize();
                window.setLocation((int) ((bounds.width / 2) - (size.getWidth() / 2)), (int) ((bounds.height / 2) - (size.getHeight() / 2)));
            default:
                window.setExtendedState(state);
        }
        window.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                Window w = (Window) e.getSource();
                JBrowser.getProperties().setProperty("window.size.state", Integer.toString(w.getExtendedState()));
                w.setExtendedState(Frame.NORMAL);
                JBrowser.getProperties().setProperty("window.size.height", Integer.toString(w.getHeight()));
                JBrowser.getProperties().setProperty("window.size.width", Integer.toString(w.getWidth()));
                try {
                    JBrowser.getProperties().store();
                } catch (IOException ex) {
                    logger.log(Level.SEVERE, null, ex);
                }
            }
        });
        return window;
    }

    public static Properties getProperties() {
        return properties;
    }

    public static void main(String[] args) {
        try {
            String home;
            if (System.getProperty("jbrowser.home") == null) {
                home = System.getProperty("user.home") + System.getProperty("file.separator") + ".jbrowser";
                System.setProperty("jbrowser.home", home);
            } else {
                home = System.getProperty("jbrowser.home");
            }
            homeFolder = new File(home);
            if (!homeFolder.exists()) {
                homeFolder.mkdir();
            }
            // /var/log
            File var = new File(homeFolder, "var");
            if (!var.exists()) {
                var.mkdir();
            }
            File log = new File(var, "log");
            if (!log.exists()) {
                log.mkdir();
            }
            // services.jar folder
            File services = new File(homeFolder, "services");
            if (!services.exists()) {
                services.mkdir();
            }
            // /etc folder
            File etc = new File(homeFolder, "etc");
            if (!etc.exists()) {
                etc.mkdir();
            }
            // logging config
            File logging = new File(etc, "jbrowser.logging");
            if (!logging.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/jbrowser.logging"), logging);
            }
            try {
                LogManager.getLogManager().readConfiguration(new FileInputStream(logging));
                logger = Logger.getLogger(JBrowser.class.getName());
                logger.log(Level.INFO, "Startup JBrowser..");
                logger.log(Level.INFO, "Home: {0}", homeFolder);
            } catch (Exception ex) {
                logger.log(Level.SEVERE, null, ex);
            }
            // service config
            services = new File(etc, "jbrowser.services");
            if (!services.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/jbrowser.services"), services);
            }
            // security config
            File security = new File(homeFolder, "security");
            if (!security.exists()) {
                security.mkdir();
            }
            // JAAS
            File jaas = new File(security, "jaas");
            if (!jaas.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/jaas"), jaas);
            }
            ConfigFile loginConfig = new ConfigFile(jaas.toURI());
            Configuration.setConfiguration(loginConfig);
            // KeyStore
            File keystore = new File(security, "keystore.jks");
            if (!keystore.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/keystore.jks"), keystore);
            }
            // Policy
            File policy = new File(security, "policy");
            if (!policy.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/policy"), policy);
            }
            PolicyFile policyFile = new PolicyFile(policy.toURI().toURL());
            Policy.setPolicy(policyFile);
            // Window
            File config = new File(etc, "jbrowser.window");
            if (!config.exists()) {
                FileUtils.copyInputStreamToFile(JBrowser.class.getResourceAsStream("/defaults/jbrowser.window"), config);
            }
            properties = new Properties().load(config);
            String lookAndFeel = properties.getProperty("window.look_and_feel");
            if (lookAndFeel != null && !lookAndFeel.isEmpty()) {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if (lookAndFeel.equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            }
            // SecurityManager
            System.setSecurityManager(DefaultSecurityManagerService.getInstance());
            // Show Window
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    newWindow().setVisible(true);
                }
            });
            logger.log(Level.INFO, "JBrowser started up.");
        } catch (Exception ex) {
            logger.log(Level.SEVERE, "Cant start JBrowser", ex);
        }
    }
}
